<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Text in Cairo</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="cairo, graphics, C, 2D vector library, text">
<meta name="description" content="In this chapter of the Cairo graphics 
tutorial, we will work with text.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Text in Cairo</h1>


<p>
In this part of the Cairo graphics tutorial, we will work with text.
</p>

<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* NewSquare */
google_ad_slot = "0364418177";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script>

<h2>Soulmate</h2>

<p>
In the first example, we will display some lyrics on the GTK+ window.
</p>

<pre class="code">
static void do_drawing(cairo_t *cr)
{
  cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); 

  cairo_select_font_face(cr, "Purisa",
      CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_BOLD);

  cairo_set_font_size(cr, 13);

  cairo_move_to(cr, 20, 30);
  cairo_show_text(cr, "Most relationships seem so transitory");  
  cairo_move_to(cr, 20, 60);
  cairo_show_text(cr, "They're all good but not the permanent one");

  cairo_move_to(cr, 20, 120);
  cairo_show_text(cr, "Who doesn't long for someone to hold");

  cairo_move_to(cr, 20, 150);
  cairo_show_text(cr, "Who knows how to love you without being told");
  cairo_move_to(cr, 20, 180);
  cairo_show_text(cr, "Somebody tell me why I'm on my own");
  cairo_move_to(cr, 20, 210);
  cairo_show_text(cr, "If there's a soulmate for everyone");    
}
</pre>

<p>
In this example, we display part of the lyrics from the Natasha 
Bedingfield's Soulmate song.
</p>

<pre class="explanation">
cairo_select_font_face(cr, "Purisa",
   CAIRO_FONT_SLANT_NORMAL,
   CAIRO_FONT_WEIGHT_BOLD);
</pre>

<p>
Here we select the font face. The function takes three parameters, the 
font family, font slant and the font weight.
</p>

<pre class="explanation">
cairo_set_font_size(cr, 13);
</pre>

<p>
Here we specify the font size.
</p>

<pre class="explanation">
cairo_move_to(cr, 20, 30);
cairo_show_text(cr, "Most relationships seem so transitory"); 
</pre>

<p>
We display the text on the window by specifying the position of the text and 
calling the <code>cairo_show_text()</code> function.
</p>

<img src="/img/gfx/cairoc/soulmate.png" alt="Soulmate">
<div class="figure">Figure: Soulmate</div>


<h2>Centered text</h2>

<p>
Next we will show, how to center text on the window.
</p>

<pre class="code">
static void do_drawing(cairo_t *cr, GtkWidget *widget)
{
  cairo_text_extents_t extents;
  
  GtkWidget *win = gtk_widget_get_toplevel(widget);
  
  gint w, h;
  gtk_window_get_size(GTK_WINDOW(win), &amp;w, &amp;h);    

  cairo_select_font_face(cr, "Courier",
      CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_BOLD);

  cairo_set_font_size(cr, 60);
  
  cairo_text_extents(cr, "ZetCode", &amp;extents);

  cairo_move_to(cr, w/2 - extents.width/2, h/2);  
  cairo_show_text(cr, "ZetCode");    
}
</pre>

<p>
The code will center a text on the window. It remains centered, even
if we resize the window.
</p>

<pre class="explanation">
GtkWidget *win = gtk_widget_get_toplevel(widget);

gint w, h;
gtk_window_get_size(GTK_WINDOW(win), &amp;w, &amp;h);    
</pre>

<p>
To center a text on the window, it is necessary to get the size of
of the parent window.
</p>

<pre class="explanation">
cairo_select_font_face(cr, "Courier",
    CAIRO_FONT_SLANT_NORMAL,
    CAIRO_FONT_WEIGHT_BOLD);

cairo_set_font_size(cr, 60);
</pre>

<p>
We select a font and its size to be displayed. 
</p>

<pre class="explanation">
cairo_text_extents(cr, "ZetCode", &amp;extents);
</pre>

<p>
We get the text extents. These are some numbers that describe
the text. We need the width of the text for our example.
</p>

<pre class="explanation">
cairo_move_to(cr, w/2 - extents.width/2, h/2);  
cairo_show_text(cr, "ZetCode");   
</pre>

<p>
We position the text into the middle of the window and
show it using the <code>cairo_show_text()</code> method.
</p>

<img src="/img/gfx/cairoc/centered.png" alt="Centered text">
<div class="figure">Figure: Centered text</div>

<h2>Shaded text</h2>

<p>
Now we will show a shaded text on the window. 
</p>

<pre class="code">
static void do_drawing(cairo_t *cr, GtkWidget *widget)
{
  cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, 50);

  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_move_to(cr, 40, 60);  
  cairo_show_text(cr, "ZetCode");  
  
  cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
  cairo_move_to(cr, 43, 63);  
  cairo_show_text(cr, "ZetCode");    
}
</pre>

<p>
To create a shade, we draw the text twice. In different 
colours. The second text is moved a bit to the right and
bottom. 
</p>

<pre class="explanation">
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_move_to(cr, 40, 60);  
cairo_show_text(cr, "ZetCode"); 
</pre>

<p>
The first text is drawn in black ink. It serves as a shade.
</p>

<pre class="explanation">
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
cairo_move_to(cr, 43, 63);  
cairo_show_text(cr, "ZetCode");  
</pre>

<p>
The second text is drawn in some gray ink. It is moved by 3px to 
the right and to the bottom.
</p>

<img src="/img/gfx/cairoc/shaded.png" alt="Shaded text">
<div class="figure">Figure: Shaded text</div>

<h2>Text filled with gradient</h2>

<p>
The following example will create a nice effect. We will
fill a text with some linear gradient.
</p>

<pre class="code">
static void do_drawing(cairo_t *cr, GtkWidget *widget)
{  
  cairo_pattern_t *pat; 
  
  cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
  cairo_paint(cr);
  
  gint h = 90;
  
  cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_ITALIC, 
      CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, h);
  
  pat = cairo_pattern_create_linear(0, 15, 0, h*0.8);
  cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
  cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0);
  cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
                  
  cairo_move_to(cr, 15, 80);
  cairo_text_path(cr, "ZetCode");
  cairo_set_source(cr, pat);
  cairo_fill(cr);
}
</pre>

<p>
We draw a text on the window filled with a linear gradient.
The colours are some orange colours.
</p>

<pre class="explanation">
cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
cairo_paint(cr);
</pre>

<p>
To make it more visually appealing, we paint the background in 
dark gray colour.
</p>

<pre class="explanation">
pat = cairo_pattern_create_linear(0, 15, 0, h*0.8);
cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0);
cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
</pre>

<p>
The linear gradient is created. 
</p>

<pre class="explanation">
cairo_move_to(cr, 15, 80);
cairo_text_path(cr, "ZetCode");
cairo_set_source(cr, pat);
cairo_fill(cr);
</pre>

<p>
The text is displayed on the window. We use the gradient as a 
source for painting.
</p>

<img src="/img/gfx/cairoc/gradient_text.png" alt="Text filled with gradient">
<div class="figure">Figure: Text filled with gradient</div>


<h2>Glyphs</h2>

<p>
The <code>cairo_show_text()</code> method is only suitable for simple text
rendering. Cairo developers call it a toy method. More professional text
rendering is done with glyphs. A <b>glyph</b> is a graphic symbol which
provides a form for a character. A character provides a meaning. It can 
have multiple glyphs. A character has no intrinsic appearance. 
A glyph has no intrinsic meaning.
</p>

<p>
Note that many common programming requirements conserning text are
addressed by the Pango library.
</p>

<pre class="code">
static void do_drawing(cairo_t *cr, GtkWidget *widget)
{    
  cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL,
      CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 13);

  const int n_glyphs = 20 * 35;
  cairo_glyph_t glyphs[n_glyphs];

  gint i = 0;  
  gint x, y;
  
  for (y=0; y&lt;20; y++) {
      for (x=0; x&lt;35; x++) {
          glyphs[i] = (cairo_glyph_t) {i, x*15 + 20, y*18 + 20};
          i++;
      }
  }
  
  cairo_show_glyphs(cr, glyphs, n_glyphs);
} 
</pre>

<p>
This code shows 700 glyphs of a chosen font. 
</p>

<pre class="explanation">
const int n_glyphs = 20 * 35;
cairo_glyph_t glyphs[n_glyphs];
</pre>

<p>
The glyphs array will store three integer values. 
The first value is the index of the glyph to the chosen 
font type. The second and the third values are x, y 
positions of a glyph.
</p>

<pre class="explanation">
cairo_show_glyphs(cr, glyphs, n_glyphs);
</pre>

<p>
The <code>cairo_show_glyphs()</code> method shows the glyphs
on the window.
</p>

<p>
This chapter covered text in Cairo.
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified December 10, 2012  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

